package com.huaxin.hxmoduleworkorder.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaxin.hxmoduleworkorder.common.LocationUtils;
import com.huaxin.hxmoduleworkorder.common.UserContext;
import com.huaxin.hxmoduleworkorder.common.enums.MaintenanceOrderElectricianTaskOperation;
import com.huaxin.hxmoduleworkorder.common.enums.MaintenanceOrderElectricianTaskStatus;
import com.huaxin.hxmoduleworkorder.common.enums.MaintenanceOrderOperatorRole;
import com.huaxin.hxmoduleworkorder.common.enums.MaintenanceOrderStatus;
import com.huaxin.hxmoduleworkorder.dto.ResponseCode;
import com.huaxin.hxmoduleworkorder.dto.ResponseResult;
import com.huaxin.hxmoduleworkorder.dto.request.*;
import com.huaxin.hxmoduleworkorder.dto.response.MaintenanceOrderElectricianTaskDetailRespDto;
import com.huaxin.hxmoduleworkorder.dto.response.MaintenanceOrderElectricianTaskSummaryRespDto;
import com.huaxin.hxmoduleworkorder.event.MaintenanceOrderElectricianTaskStatusChangedEvent;
import com.huaxin.hxmoduleworkorder.feignclients.SysFeignService;
import com.huaxin.hxmoduleworkorder.mapper.MaintenanceOrderElectricianTaskMapper;
import com.huaxin.hxmoduleworkorder.mapper.MaintenanceOrderMapper;
import com.huaxin.hxmoduleworkorder.mapping.MaintenanceOrderElectricianTaskMapping;
import com.huaxin.hxmoduleworkorder.models.MaintenanceOrder;
import com.huaxin.hxmoduleworkorder.models.MaintenanceOrderElectricianTask;
import com.huaxin.hxmoduleworkorder.models.MaintenanceOrderElectricianTaskProcess;
import com.huaxin.hxmoduleworkorder.models.MaintenanceOrderElectricianTaskResult;
import com.huaxin.hxmoduleworkorder.service.MaintenanceOrderElectricianTaskProcessService;
import com.huaxin.hxmoduleworkorder.service.MaintenanceOrderElectricianTaskResultService;
import com.huaxin.hxmoduleworkorder.service.MaintenanceOrderElectricianTaskService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.webjars.NotFoundException;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class MaintenanceOrderElectricianTaskServiceImpl extends ServiceImpl<MaintenanceOrderElectricianTaskMapper, MaintenanceOrderElectricianTask> implements MaintenanceOrderElectricianTaskService {
    private final ApplicationContext applicationContext;
    private final MaintenanceOrderElectricianTaskMapping mapping;
    private final MaintenanceOrderElectricianTaskMapper mapper;
    private final MaintenanceOrderElectricianTaskProcessService processService;
    private final MaintenanceOrderElectricianTaskResultService resultService;
    private final MaintenanceOrderMapper orderMapper;
    private final LocationUtils locationUtils;
    private final ApplicationEventPublisher eventPublisher;
    private final SysFeignService sysFeignService;

    /* *********************************************************************
     * 工单任务基础 CRUD 操作
     ********************************************************************* */

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createTasks(List<MaintenanceOrderElectricianTaskCreateReqDTO> in) {
        if (in == null || in.isEmpty()) {
            throw new IllegalArgumentException("至少需要分配一名电工");
        }

        String orderId = in.get(0).getMaintenanceOrderId();

        // 查询已分配的处理中的电工任务，避免重复
        LambdaQueryWrapper<MaintenanceOrderElectricianTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MaintenanceOrderElectricianTask::getMaintenanceOrderId, orderId)
                .in(MaintenanceOrderElectricianTask::getStatus, Set.of(MaintenanceOrderElectricianTaskStatus.ASSIGNED, MaintenanceOrderElectricianTaskStatus.ACCEPTED, MaintenanceOrderElectricianTaskStatus.ON_SITE, MaintenanceOrderElectricianTaskStatus.PROCESSING));
        List<String> existingElectricianIds = this.list(wrapper).stream().map(MaintenanceOrderElectricianTask::getElectricianId).toList();

        // 过滤出新电工，排除已分配的
        List<MaintenanceOrderElectricianTaskCreateReqDTO> newElectricians = in.stream()
                .filter(task -> !existingElectricianIds.contains(task.getElectricianId()))
                .toList();

        // 去重
        List<MaintenanceOrderElectricianTaskCreateReqDTO> uniqueElectricians = newElectricians.stream()
                .collect(Collectors.groupingBy(MaintenanceOrderElectricianTaskCreateReqDTO::getElectricianId))
                .values()
                .stream()
                .map(maintenanceOrderElectricianTaskCreateReqDTOS -> maintenanceOrderElectricianTaskCreateReqDTOS.get(0))
                .toList();

        if (uniqueElectricians.isEmpty()) {
            // 所有电工都已分配过，无需创建
            return;
        }

        List<MaintenanceOrderElectricianTask> newTasks = mapping.toEntityList(uniqueElectricians);
        this.saveBatch(newTasks);

        List<MaintenanceOrderElectricianTaskProcessCreateReqDTO> processDTOs = newTasks.stream()
                .map(task -> MaintenanceOrderElectricianTaskProcessCreateReqDTO.builder()
                        .MaintenanceOrderId(orderId)
                        .maintenanceOrderElectricianTaskId(task.getId())
                        .action(MaintenanceOrderElectricianTaskOperation.ASSIGN)
                        .fromStatus(MaintenanceOrderElectricianTaskStatus.UNKNOWN)
                        .toStatus(MaintenanceOrderElectricianTaskStatus.ASSIGNED)
                        .operatorRole(MaintenanceOrderOperatorRole.of(in.get(0).getOperatorRole()))
                        .operatorId(UserContext.getCurrentUserId())
                        .operatorLongitude(in.get(0).getOperatorLongitude())
                        .operatorLatitude(in.get(0).getOperatorLatitude())
                        .remarks("工单电工任务分配给：" + task.getElectricianId())
                        .isCompleted(1)
                        .build())
                .collect(Collectors.toList());
        processService.createProcesses(processDTOs);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTasks(MaintenanceOrderElectricianTaskUpdateReqDTO in) {
        if (in == null || in.getTasks() == null || in.getTasks().isEmpty()) {
            return;
        }

        List<String> taskIds = in.getTasks().stream().map(MaintenanceOrderElectricianTaskUpdate_Task_ReqDTO::getTaskId).toList();
        LambdaQueryWrapper<MaintenanceOrderElectricianTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(MaintenanceOrderElectricianTask::getId, taskIds);
        List<MaintenanceOrderElectricianTask> entityList = this.baseMapper.selectList(wrapper);

        // 比较taskIds和entityList，如果有任务不存在，则抛出异常
        if (taskIds.size() != entityList.size()) {
            List<String> missingTaskIds = taskIds.stream().filter(taskId -> !entityList.stream().map(MaintenanceOrderElectricianTask::getId).toList().contains(taskId)).toList();
            if (!missingTaskIds.isEmpty()) {
                throw new NotFoundException("任务不存在：" + String.join(",", missingTaskIds));
            }
        }

        for (MaintenanceOrderElectricianTask task : entityList) {
            if (!this.canOperate(task.getId(), MaintenanceOrderElectricianTaskOperation.EDIT, MaintenanceOrderOperatorRole.of(in.getOperatorRole()))) {
                throw new IllegalStateException("任务 " + task.getId() + " 当前状态不允许编辑：" + task.getStatus());
            }
            MaintenanceOrderElectricianTaskUpdate_Task_ReqDTO taskDTO;
            taskDTO = in.getTasks().stream()
                    .filter(t -> t.getTaskId().equals(task.getId()))
                    .findFirst()
                    .orElseThrow(() -> new IllegalArgumentException("未找到对应的任务DTO，任务ID：" + task.getId()));
            task.setResponsibility(taskDTO.getResponsibility());
        }

        this.updateBatchById(entityList);
    }

    @Override
    public MaintenanceOrderElectricianTask get(String id) {
        if (StringUtils.isBlank(id)) {
            throw new IllegalArgumentException("工单电工任务ID不能为空");
        }
        MaintenanceOrderElectricianTask entity = this.getById(id);
        if (entity == null) {
            throw new NotFoundException("工单电工任务不存在");
        }
        return entity;
    }

    @Override
    public void deleteByOrderId(String orderId) {
        if (StringUtils.isBlank(orderId)) {
            throw new IllegalArgumentException("工单ID不能为空");
        }
        LambdaQueryWrapper<MaintenanceOrderElectricianTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MaintenanceOrderElectricianTask::getMaintenanceOrderId, orderId);
        applicationContext.getBean(MaintenanceOrderElectricianTaskService.class).remove(wrapper);
    }

    /* *********************************************************************
     * 电工任务状态与流程管理
     ********************************************************************* */

    @Override
    public ResponseResult<String> getTaskStatus(String taskId) {
        MaintenanceOrderElectricianTask task = this.get(taskId);
        return ResponseResult.ok(task.getStatus().getCode());
    }

    /*----------------------------------------------------------------------------------------------------------------*/

    /*
     * 工单电工任务操作权限控制
     * 操作	                允许的状态	                                  角色	            说明
     * ACCEPT	            ASSIGNED	                                  电工	            接单，状态 → ACCEPTED
     * REJECT	            ASSIGNED, ACCEPTED, ON_SITE, PROCESSING	      电工	            拒单，状态 → REJECTED
     * ON_SITE	            ACCEPTED	                                  电工	            标记到场，状态 → ON_SITE
     * START_PROCESS	    ON_SITE	                                      电工	            开始处理，状态 → PROCESSING
     * RESOLVE	            PROCESSING	                                  电工	            提交解决，状态 → RESOLVED
     * VIEW	                所有状态	                                      电工	            查看任务详情
     * EDIT                 所有状态                                       管理员、主修电工     更新任务的责任描述
     */

    /**
     * 获取当前用户在指定任务上可执行的操作列表
     */
    public List<MaintenanceOrderElectricianTaskOperation> getAvailableOperations(String taskId, MaintenanceOrderOperatorRole operatorRole) {
        if (taskId == null || operatorRole == null) {
            return List.of();
        }
        MaintenanceOrderElectricianTask task = this.getById(taskId);
        return this.getAvailableOperations(task, operatorRole);
    }

    private List<MaintenanceOrderElectricianTaskOperation> getAvailableOperations(MaintenanceOrderElectricianTask task, MaintenanceOrderOperatorRole operatorRole) {
        if (task == null || task.getStatus() == null) {
            return List.of();
        }

        List<MaintenanceOrderElectricianTaskOperation> operations = new ArrayList<>();

        boolean isAdmin = MaintenanceOrderOperatorRole.ADMIN.equals(operatorRole);
        String currentUserId = UserContext.getCurrentUserId();
        // 当前用户是否是任务的电工
        boolean isAssignedElectrician = MaintenanceOrderOperatorRole.ELECTRICIAN.equals(operatorRole) && task.getElectricianId().equals(currentUserId);

        // 不是管理员或分配的电工没有操作权限
        if (!isAdmin && !isAssignedElectrician) {
            return operations;
        }

        operations.add(MaintenanceOrderElectricianTaskOperation.VIEW);

        // 管理员和主修电工都可以编辑
        boolean isLeadElectrician = false;
        MaintenanceOrder order = this.orderMapper.selectById(task.getMaintenanceOrderId());
        if (order != null) {
            isLeadElectrician = MaintenanceOrderOperatorRole.ELECTRICIAN.equals(operatorRole) && order.getElectricianId().equals(currentUserId);
        }
        if (isAdmin || isLeadElectrician) {
            operations.add(MaintenanceOrderElectricianTaskOperation.EDIT);
        }

        //只有分配的电工可以执行其它操作
        if (!isAssignedElectrician) {
            return operations;
        }

        // 终态：只允许 VIEW
        if (task.getStatus().isTerminal()) {
            return operations;
        }

        // 根据当前状态添加可执行操作
        switch (task.getStatus()) {
            case ASSIGNED:
                operations.add(MaintenanceOrderElectricianTaskOperation.ACCEPT);
                operations.add(MaintenanceOrderElectricianTaskOperation.REJECT);
                break;

            case ACCEPTED:
                operations.add(MaintenanceOrderElectricianTaskOperation.ON_SITE);
                operations.add(MaintenanceOrderElectricianTaskOperation.REJECT);
                break;

            case ON_SITE:
                operations.add(MaintenanceOrderElectricianTaskOperation.START_PROCESS);
                operations.add(MaintenanceOrderElectricianTaskOperation.REJECT);
                break;

            case PROCESSING:
                operations.add(MaintenanceOrderElectricianTaskOperation.RESOLVE);
                operations.add(MaintenanceOrderElectricianTaskOperation.REJECT);
                break;

            // 其他状态（如 CANCELLED）已在 terminal 判断中排除
        }

        return operations;
    }

    /**
     * 判断某角色是否可以对指定任务执行某操作
     */
    public Boolean canOperate(String taskId, MaintenanceOrderElectricianTaskOperation operation, MaintenanceOrderOperatorRole operatorRole) {
        if (taskId == null || operation == null || operatorRole == null) {
            return false;
        }

        // 1. 查询工单电工任务
        MaintenanceOrderElectricianTask task = this.getById(taskId);
        if (task == null) {
            return false; // 工单电工任务不存在
        }

        // 2. 获取当前角色在该状态下的所有可执行操作
        List<MaintenanceOrderElectricianTaskOperation> allowedOps = getAvailableOperations(taskId, operatorRole);

        // 3. 判断目标操作是否在允许列表中
        return allowedOps.contains(operation);
    }

    private Boolean canOperate(String taskId, MaintenanceOrderElectricianTaskOperation operation, String operatorRole) {
        return canOperate(taskId, operation, MaintenanceOrderOperatorRole.of(operatorRole));
    }

    /*----------------------------------------------------------------------------------------------------------------*/

    /*----------------------------------------------------------------------------------------------------------------*/

    /**
     * 更新电工任务状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatus(MaintenanceOrderElectricianTaskUpdateStatusReqDto in, Consumer<MaintenanceOrderElectricianTask> additionalUpdater) {
        MaintenanceOrderElectricianTask task = this.get(in.getTaskId());
        if (task == null) {
            throw new IllegalArgumentException("工单任务不存在");
        }
        if (task.getStatus().isTerminal()) {
            return;
        }

        MaintenanceOrderElectricianTaskStatus oldStatus = task.getStatus();
        MaintenanceOrderElectricianTaskStatus targetStatus = in.getTargetStatus();

        // 设置新状态
        task.setStatus(targetStatus);

        // 根据状态自动设置时间字段
        if (MaintenanceOrderElectricianTaskStatus.ASSIGNED.equals(targetStatus)) {
            task.setAssignAt(LocalDateTime.now());
        } else if (MaintenanceOrderElectricianTaskStatus.ACCEPTED.equals(targetStatus)) {
            task.setAcceptAt(LocalDateTime.now());
        } else if (MaintenanceOrderElectricianTaskStatus.REJECTED.equals(targetStatus)) {
            task.setRejectAt(LocalDateTime.now());
        } else if (MaintenanceOrderElectricianTaskStatus.ON_SITE.equals(targetStatus)) {
            task.setOnSiteAt(LocalDateTime.now());
        } else if (MaintenanceOrderElectricianTaskStatus.RESOLVED.equals(targetStatus)) {
            task.setResolveAt(LocalDateTime.now());
        }

        // 可根据需要扩展其他状态时间字段

        // 执行额外字段设置（如驳回原因）
        if (additionalUpdater != null) {
            additionalUpdater.accept(task);
        }

        this.updateById(task);

        // 添加工单进度记录
        MaintenanceOrderOperatorRole operatorRole = MaintenanceOrderOperatorRole.of(in.getOperatorRole());
        processService.create(MaintenanceOrderElectricianTaskProcessCreateReqDTO.builder()
                .MaintenanceOrderId(task.getMaintenanceOrderId())
                .maintenanceOrderElectricianTaskId(task.getId())
                .action(in.getAction())
                .fromStatus(oldStatus)
                .toStatus(targetStatus)
                .operatorRole(operatorRole)
                .operatorId(UserContext.getCurrentUserId())
                .operatorLongitude(in.getOperatorLongitude())
                .operatorLatitude(in.getOperatorLatitude())
                .remarks(in.getRemarks())
                .isCompleted(1)
                .build());

        // 触发通知，自动推进工单状态
        eventPublisher.publishEvent(MaintenanceOrderElectricianTaskStatusChangedEvent.of(this, task.getId(), oldStatus, targetStatus, UserContext.getCurrentUserId(), operatorRole));
    }

    /**
     * 批量更新电工任务状态，系统内部调用，不会触发通知
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStatusByOrderId(String orderId, MaintenanceOrderElectricianTaskStatus targetStatus, MaintenanceOrderElectricianTaskOperation action, String remarks) {
        List<MaintenanceOrderElectricianTask> tasks = this.listByOrderId(orderId);
        // 过滤出可更新的任务（非终态）
        List<MaintenanceOrderElectricianTask> editableTasks = tasks.stream()
                .filter(task -> !task.getStatus().isTerminal())
                .toList();
        if (editableTasks.isEmpty()) {
            return;
        }

        // 记录状态变更
        List<MaintenanceOrderElectricianTaskStatus> oldStatuses = editableTasks.stream()
                .map(MaintenanceOrderElectricianTask::getStatus)
                .toList();

        editableTasks.forEach(task -> {
            task.setStatus(targetStatus);
        });
        this.updateBatchById(tasks);

        // 添加工单进度记录
        List<MaintenanceOrderElectricianTaskProcessCreateReqDTO> processDTOs = editableTasks.stream()
                .map(task -> MaintenanceOrderElectricianTaskProcessCreateReqDTO.builder()
                        .MaintenanceOrderId(orderId)
                        .maintenanceOrderElectricianTaskId(task.getId())
                        .action(action)
                        .fromStatus(oldStatuses.get(editableTasks.indexOf(task)))
                        .toStatus(targetStatus)
                        .operatorRole(MaintenanceOrderOperatorRole.SYSTEM)
                        .remarks(remarks)
                        .isCompleted(1)
                        .build())
                .collect(Collectors.toList());
        processService.createProcesses(processDTOs);
    }

    /*----------------------------------------------------------------------------------------------------------------*/

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<String> accept(MaintenanceOrderElectricianTaskAcceptReqDto in) {
        MaintenanceOrderElectricianTask task = this.getById(in.getTaskId());
        if (!canOperate(in.getTaskId(), MaintenanceOrderElectricianTaskOperation.ACCEPT, in.getOperatorRole())) {
            throw new IllegalStateException("当前状态不允许接单：" + task.getStatus());
        }
        this.updateStatus(MaintenanceOrderElectricianTaskUpdateStatusReqDto.builder()
                .taskId(task.getId())
                .action(MaintenanceOrderElectricianTaskOperation.ACCEPT)
                .targetStatus(MaintenanceOrderElectricianTaskStatus.ACCEPTED)
                .operatorRole(in.getOperatorRole())
                .operatorLongitude(in.getOperatorLongitude())
                .operatorLatitude(in.getOperatorLatitude())
                .remarks(in.getRemarks())
                .build(), null);
        return ResponseResult.ok("接单成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<String> onSite(MaintenanceOrderElectricianTaskOnSiteReqDto in) {
        MaintenanceOrderElectricianTask task = this.getById(in.getTaskId());

        if (!canOperate(in.getTaskId(), MaintenanceOrderElectricianTaskOperation.ON_SITE, in.getOperatorRole())) {
            throw new IllegalStateException("当前状态不允许标记到达：" + task.getStatus());
        }

        // 判断定位是否正确
        MaintenanceOrder order = orderMapper.selectById(task.getMaintenanceOrderId());
        if (order == null) {
            return ResponseResult.failure(ResponseCode.CUSTOM_BUSINESS_ERROR, "工单不存在！", null);
        }
        if (!this.isLocationValid(order.getAddressLongitude(), order.getAddressLatitude(), in.getOperatorLongitude(), in.getOperatorLatitude())) {
            return ResponseResult.failure(ResponseCode.CUSTOM_BUSINESS_ERROR, "定位信息错误！", null);
        }

        this.updateStatus(MaintenanceOrderElectricianTaskUpdateStatusReqDto.builder()
                .taskId(task.getId())
                .action(MaintenanceOrderElectricianTaskOperation.ON_SITE)
                .targetStatus(MaintenanceOrderElectricianTaskStatus.ON_SITE)
                .operatorRole(in.getOperatorRole())
                .operatorLongitude(in.getOperatorLongitude())
                .operatorLatitude(in.getOperatorLatitude())
                .remarks(in.getRemarks())
                .build(), null);
        return ResponseResult.ok("标记到达成功！");
    }

    /**
     * 判断实际位置是否在目标位置的允许误差范围内
     *
     * @param targetLonString 目标经度
     * @param targetLatString 目标纬度
     * @param actualLonString 实际经度
     * @param actualLatString 实际纬度
     * @return true 表示位置有效
     */
    public boolean isLocationValid(
            String targetLonString, String targetLatString,
            String actualLonString, String actualLatString) {

        // 1. 空值判断
        if (targetLonString == null || targetLatString == null || actualLonString == null || actualLatString == null) {
            return false;
        }

        // 2. 从字典表读取误差阈值（单位：米）
        double threshold = sysFeignService.getLocThresholdMaintenance();

        // 3. 判断是否在范围内
        Optional<LocationUtils.Coordinate> targetCoordinate = LocationUtils.Coordinate.of(targetLonString, targetLatString);
        Optional<LocationUtils.Coordinate> actualCoordinate = LocationUtils.Coordinate.of(actualLonString, actualLatString);
        if (targetCoordinate.isEmpty() || actualCoordinate.isEmpty()) {
            return false;
        }
        return LocationUtils.isWithinDistance(targetCoordinate.get().lon, targetCoordinate.get().lat, actualCoordinate.get().lon, actualCoordinate.get().lat, threshold);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<String> startProcess(MaintenanceOrderElectricianTaskProcessingReqDto in) {
        MaintenanceOrderElectricianTask task = this.getById(in.getTaskId());
        if (!canOperate(in.getTaskId(), MaintenanceOrderElectricianTaskOperation.START_PROCESS, in.getOperatorRole())) {
            throw new IllegalStateException("当前状态不允许开始工作：" + task.getStatus());
        }
        this.updateStatus(MaintenanceOrderElectricianTaskUpdateStatusReqDto.builder()
                .taskId(task.getId())
                .action(MaintenanceOrderElectricianTaskOperation.START_PROCESS)
                .targetStatus(MaintenanceOrderElectricianTaskStatus.PROCESSING)
                .operatorRole(in.getOperatorRole())
                .operatorLongitude(in.getOperatorLongitude())
                .operatorLatitude(in.getOperatorLatitude())
                .remarks(in.getRemarks())
                .build(), null);
        return ResponseResult.ok("开始工作！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<String> submitResult(MaintenanceOrderElectricianTaskSubmitResultReqDto in) {
        MaintenanceOrderElectricianTask task = this.getById(in.getTaskId());

        // 状态检查：只允许在 "PROCESSING" 时提交
        if (!MaintenanceOrderElectricianTaskStatus.PROCESSING.equals(task.getStatus())) {
            throw new IllegalArgumentException("当前状态 [" + task.getStatus() + "] 不允许提交处理结果！");
        }

        // 保存或更新结果
        MaintenanceOrderElectricianTaskResult result = resultService.getByElectricianTaskId(task.getId());
        if (result == null) {
            Boolean success = resultService.create(MaintenanceOrderElectricianTaskResultCreateReqDTO.builder()
                    .maintenanceOrderId(task.getMaintenanceOrderId())
                    .maintenanceOrderElectricianTaskId(task.getId())
                    .electricianId(in.getElectricianId())
                    .problemDescription(in.getProblemDescription())
                    .solution(in.getSolution())
                    .workHours(in.getWorkHours())
                    .partsUsed(in.getPartsUsed())
                    .photoUrls(in.getPhotoUrls())
                    .signImageUrl(in.getSignImageUrl())
                    .signImageBase64Data(in.getSignImageBase64Data())
                    .build());
            if (!success) {
                return ResponseResult.failure(ResponseCode.CUSTOM_BUSINESS_ERROR, "处理结果保存失败！", null);
            }
        } else {
            boolean success = resultService.update(MaintenanceOrderElectricianTaskResultUpdateReqDTO.builder()
                    .id(result.getId())
                    .maintenanceOrderId(task.getMaintenanceOrderId())
                    .maintenanceOrderElectricianTaskId(task.getId())
                    .electricianId(in.getElectricianId())
                    .problemDescription(in.getProblemDescription())
                    .solution(in.getSolution())
                    .workHours(in.getWorkHours())
                    .partsUsed(in.getPartsUsed())
                    .photoUrls(in.getPhotoUrls())
                    .signImageUrl(in.getSignImageUrl())
                    .signImageBase64Data(in.getSignImageBase64Data())
                    .build());
            if (!success) {
                return ResponseResult.failure(ResponseCode.CUSTOM_BUSINESS_ERROR, "处理结果更新失败！", null);
            }
        }
        return ResponseResult.ok("处理结果提交成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<String> resolve(MaintenanceOrderElectricianTaskResolveReqDto in) {
        MaintenanceOrderElectricianTask task = this.getById(in.getTaskId());
        if (!canOperate(in.getTaskId(), MaintenanceOrderElectricianTaskOperation.RESOLVE, in.getOperatorRole())) {
            throw new IllegalStateException("当前状态不允许确认解决：" + task.getStatus());
        }

        // 检验工单结果
        MaintenanceOrderElectricianTaskResult result = resultService.getByElectricianTaskId(task.getId());
        if (result == null) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "请先提交处理结果！", null);
        }

        this.updateStatus(MaintenanceOrderElectricianTaskUpdateStatusReqDto.builder()
                .taskId(task.getId())
                .action(MaintenanceOrderElectricianTaskOperation.RESOLVE)
                .targetStatus(MaintenanceOrderElectricianTaskStatus.RESOLVED)
                .operatorRole(in.getOperatorRole())
                .operatorLongitude(in.getOperatorLongitude())
                .operatorLatitude(in.getOperatorLatitude())
                .remarks(in.getRemarks())
                .build(), null);
        return ResponseResult.ok("解决成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<String> reject(MaintenanceOrderElectricianTaskRejectReqDto in) {
        MaintenanceOrderElectricianTask task = this.getById(in.getTaskId());
        if (!canOperate(in.getTaskId(), MaintenanceOrderElectricianTaskOperation.REJECT, in.getOperatorRole())) {
            throw new IllegalStateException("当前状态不允许拒绝：" + task.getStatus());
        }
        this.updateStatus(MaintenanceOrderElectricianTaskUpdateStatusReqDto.builder()
                .taskId(task.getId())
                .action(MaintenanceOrderElectricianTaskOperation.REJECT)
                .targetStatus(MaintenanceOrderElectricianTaskStatus.REJECTED)
                .operatorRole(in.getOperatorRole())
                .operatorLongitude(in.getOperatorLongitude())
                .operatorLatitude(in.getOperatorLatitude())
                .remarks(in.getRemarks())
                .build(), t -> {
            t.setRejectReason(in.getRemarks());
        });
        return ResponseResult.ok("拒单成功！");
    }

    @Override
    public MaintenanceOrderStatus calculateOrderStatus(MaintenanceOrder order) {
        MaintenanceOrderStatus currentStatus = order.getStatus();

        // 如果工单已被终态关闭，不再更新
        if (currentStatus.isTerminal()) {
            return currentStatus;
        }

        List<MaintenanceOrderElectricianTask> tasks = this.listByOrderId(order.getId());
        if (tasks.isEmpty()) {
            return currentStatus;
        }

        // 统计任务状态
        long accepted = tasks.stream().filter(t -> is(t, MaintenanceOrderElectricianTaskStatus.ACCEPTED)).count();
        long onSite = tasks.stream().filter(t -> is(t, MaintenanceOrderElectricianTaskStatus.ON_SITE)).count();
        long processing = tasks.stream().filter(t -> is(t, MaintenanceOrderElectricianTaskStatus.PROCESSING)).count();
        long resolved = tasks.stream().filter(t -> is(t, MaintenanceOrderElectricianTaskStatus.RESOLVED)).count();
        long rejected = tasks.stream().filter(t -> is(t, MaintenanceOrderElectricianTaskStatus.REJECTED)).count();
        long assigned = tasks.stream().filter(t -> is(t, MaintenanceOrderElectricianTaskStatus.ASSIGNED)).count();
        long cancelled = tasks.stream().filter(t -> is(t, MaintenanceOrderElectricianTaskStatus.CANCELLED)).count();

        long total = tasks.size();
        long completed = resolved + cancelled + rejected;

        // 优先判断异常状态
        if (rejected > 0 && accepted == 0 && onSite == 0 && processing == 0 && resolved == 0) {
            return currentStatus; // 有拒单，但无人接单处理 → 保持状态
        }

        // 判断处理中：只要有1人接单并开始处理
        if (accepted > 0 || onSite > 0 || processing > 0) {
            return MaintenanceOrderStatus.PROCESSING;
        }

        // 判断已解决：所有任务都完成（解决或取消）
        if (completed == total && resolved > 0) {
            return MaintenanceOrderStatus.RESOLVED;
        }

        // 默认返回当前状态（保守）
        return currentStatus;
    }

    private boolean is(MaintenanceOrderElectricianTask task, MaintenanceOrderElectricianTaskStatus status) {
        return task.getStatus() != null && task.getStatus().equals(status);
    }

    /* *********************************************************************
     * 分页与条件查询
     ********************************************************************* */

    @Override
    public List<MaintenanceOrderElectricianTask> listByOrderId(String orderId) {
        LambdaQueryWrapper<MaintenanceOrderElectricianTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MaintenanceOrderElectricianTask::getMaintenanceOrderId, orderId);
        return this.list(wrapper);
    }

    @Override
    public Boolean existsResolvedTask(String orderId) {
        MaintenanceOrderElectricianTask task = this.baseMapper.selectOne(new LambdaQueryWrapper<MaintenanceOrderElectricianTask>()
                .eq(MaintenanceOrderElectricianTask::getMaintenanceOrderId, orderId)
                .eq(MaintenanceOrderElectricianTask::getStatus, MaintenanceOrderElectricianTaskStatus.RESOLVED));
        return task != null;
    }

    @Override
    public Boolean isAssigned(String orderId, String electricianId) {
        return this.baseMapper.exists(new LambdaQueryWrapper<MaintenanceOrderElectricianTask>()
                .eq(MaintenanceOrderElectricianTask::getMaintenanceOrderId, orderId)
                .eq(MaintenanceOrderElectricianTask::getElectricianId, electricianId));
    }

    public ResponseResult<Page<MaintenanceOrderElectricianTaskSummaryRespDto>> pageQuery(MaintenanceOrderElectricianTaskPageListReqDTO in) {
        Page<MaintenanceOrderElectricianTaskSummaryRespDto> page = new Page<>(in.getPageNum(), in.getPageSize());

        Page<MaintenanceOrderElectricianTaskSummaryRespDto> pageList = mapper.selectPageTasks(page, in);
        return ResponseResult.ok(pageList);
    }

    @Override
    public List<MaintenanceOrderElectricianTaskSummaryRespDto> getIncompleteTasks(String electricianId) {
        return mapper.selectIncompleteTasksByElectricianId(electricianId,
                Arrays.stream(MaintenanceOrderElectricianTaskStatus.getIncompleteCodes()).toList(),
                Arrays.stream(MaintenanceOrderStatus.getTerminalCodes()).toList());
    }

    @Override
    public MaintenanceOrderElectricianTaskDetailRespDto detail(String taskId) {
        MaintenanceOrderElectricianTask electricianTask = this.get(taskId);

        // 查询每个任务的结果
        MaintenanceOrderElectricianTaskResult result = resultService.getByElectricianTaskId(taskId);

        // 获取流程日志
        List<MaintenanceOrderElectricianTaskProcess> processHistory = this.processService.getProcessHistory(taskId);

        return MaintenanceOrderElectricianTaskDetailRespDto.builder()
                .electricianTask(electricianTask)
                .processHistory(processHistory)
                .result(result)
                .build();
    }

    /* *********************************************************************
     * 统计与报表
     ********************************************************************* */

    @Override
    public Map<String, Long> incompleteTaskCountByElectrician() {
        return this.baseMapper.incompleteTaskCountByElectrician(Arrays.stream(MaintenanceOrderElectricianTaskStatus.getIncompleteCodes()).toList());
    }
}